package com.yuhuihui.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 线程工具类
 *
 * @author yuhh
 * @date 2023-05-25 14:45:09
 */
public final class ThreadUtil {

    private static final Logger logger = LoggerFactory.getLogger(ThreadUtil.class);

    /**
     * 生成线程池
     *
     * @param size       线程个数
     * @param threadName 线程名
     * @return {@link ThreadPoolExecutor }
     * @author yuhh
     * @date 2023-05-25 14:45:14
     */
    public static ThreadPoolExecutor buildThreadPool(int size, String threadName){
        int processors = Runtime.getRuntime().availableProcessors();
        processors = Math.min(size, processors);
        return new ThreadPoolExecutor(processors, processors, 0L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
                new ThreadFactoryBuilder(threadName));
    }

    /**
     * 关闭线程池
     *
     * @param threadPoolExecutor 需要关闭的线程池
     * @author yuhh
     * @date 2023-05-25 14:45:19
     */
    public static void shutdownThreadPool(ThreadPoolExecutor threadPoolExecutor){
        // 通知线程池结束
        threadPoolExecutor.shutdown();

        while (true) {
            try {
                // 每隔一秒钟检查一次是否执行完毕
                if (threadPoolExecutor.awaitTermination(1, TimeUnit.SECONDS)){
                    break;
                }
            } catch (InterruptedException e) {
                logger.error("检查线程是否结束出现异常，强制结束线程池", e);
                threadPoolExecutor.shutdownNow();
            }
        }
    }

    /**
     * 使线程wait指定时间
     *
     * @param milliseconds wait的时间，单位毫秒
     * @author yuhh
     * @date 2023-05-25 14:45:23
     */
    public static void threadWait(long milliseconds){
        try {
            Object lock = new Object();
            synchronized(lock){
                lock.wait(milliseconds);
            }
        } catch (InterruptedException e) {
            logger.error("线程wait出现异常", e);
        }
    }

    /**
     * 生成可自动关闭的线程池--存活1分钟
     *
     * @param threadName 线程名
     * @return {@link ThreadPoolExecutor }
     * @author yuhh
     * @date 2023-05-25 14:45:41
     */
    public static ThreadPoolExecutor buildAutoCloseThreadPool(String threadName){
        int processors = Runtime.getRuntime().availableProcessors() * 2;
        ThreadPoolExecutor executor = new ThreadPoolExecutor(processors, processors, 60L,
                TimeUnit.SECONDS, new LinkedBlockingQueue<>(),
                new ThreadFactoryBuilder(threadName));
        // 允许核心线程超时销毁
        executor.allowCoreThreadTimeOut(true);
        return executor;
    }

    /**
     * 生成线程池
     *
     * @param threadName 线程名
     * @return {@link ThreadPoolExecutor }
     * @author yuhh
     * @date 2023-05-25 14:45:44
     */
    public static ThreadPoolExecutor buildThreadPool(String threadName){
        int processors = Runtime.getRuntime().availableProcessors() * 2;
        return new ThreadPoolExecutor(processors, processors, 0L,
                TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
                new ThreadFactoryBuilder(threadName));
    }

    /**
     * 线程工厂构造内部类
     *
     * @author yuhh
     * @date 2023-05-25 14:45:52
     * @see ThreadFactory
     */
    private static class ThreadFactoryBuilder implements ThreadFactory {

        /**
         * 线程下标
         */
        private final AtomicInteger counter;
        /**
         * 线程名
         */
        private final String threadName;

        private ThreadFactoryBuilder(String threadName){
            this.threadName = threadName;
            this.counter = new AtomicInteger(1);
        }

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, threadName + "-" + counter.getAndIncrement());
        }
    }

    private ThreadUtil(){

    }
}
